home *** CD-ROM | disk | FTP | other *** search
- segment GUSSound
- assume cs:GUSSound,ds:GUSSound
-
- StartSoundSeg = $
-
- proc MUS
- push ax bx cx dx bp ds es
- push ax
- mov ax,cs
- mov ds,ax
- mov es,ax
- pop ax
- cld
- cmp bx,0fh
- ja @@HigherThanWeCount
- cmp bx,0
- jz @@DoIt
- cmp [cs:MUSOK],1
- jnz @@HigherThanWeCount
- @@DoIt: shl bx,1
- call [Word bx+JumpTable]
- @@HigherThanWeCount:
- pop es ds bp dx cx bx ax
- retf
- endp MUS
-
- db 13,10,'Gravis UltraSound MOD Routines v2.1',0
- db 13,10,'By Joshua C. Jensen',0
- JumpTable dw offset MUS_Init ; Function 00
- dw offset MUS_Close ; Function 01
- dw offset MUS_SetVars ; Function 02
- dw offset MUS_Nothing ; Function 03
- dw offset MUS_PlayMusic ; Function 04
- dw offset MUS_StopMusic ; Function 05
- dw offset MUS_Nothing ; Function 06
- dw offset MUS_SpeakerOn ; Function 07
- dw offset MUS_SpeakerOff ; Function 08
- dw offset MUS_ReturnInfo ; Function 09
- dw offset MUS_SetInfo ; Function 0A
- dw offset MUS_RetVoice ; Function 0B
- dw offset MUS_RetMusicStatus ; Function 0C
- dw offset MUS_DumpSampleDRAM ; Function 0D
-
- ;include "ptable.inc"
-
- MUSOK db 0
- PS16Header:
- Sig db 'PS16■'
- SongName db 75 dup (0)
- SongLen db 0
- numpatterns db 0
- commentofs dd 0
- Sequences db 128 dup (0)
- Samples db 31*size PS16Sample dup (0)
- PS16Size = $-PS16Header
-
- PatternLoc dw 64 dup (0)
- InsLoc dd 32 dup (0)
- NumPatterns dw 0
- Mus SMus <>
- NumLines db 0
- MusBuf dw 0
- ChannelMap db 32 dup (0)
- ChannelPriority db 32 dup (0)
-
- include "vect.rt"
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_Nothing - Dead...
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_Nothing near
- ret
- endp MUS_Nothing
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_Init - Initialize the music routines.
- ; AX - GF1 IRQ (0 for detect)
- ; CX - MIDI IRQ
- ; DX - Base port (0 for detect)
- ; SI - DMA IN
- ; DI - DMA OUT
- ; Carry set - No Gravis Ultrasound
- ; Returns:
- ; SI - IRQ
- ; DI - Port
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_Init near
- call u_DetectGUS
- jnb @@FoundGUS
- xor si,si
- xor di,di
- ret
- @@FoundGUS: mov bx,[cs:GUSIRQ]
- mov si,cs
- mov di,offset GUSInt
- call SetVect
- mov [Word cs:IntStore],di
- mov [Word cs:IntStore+2],si
- call u_Reset
- call MUS_SetMaxVolume
- mov [Word cs:Mus+(offset (SMus).HeaderLoc)],offset PS16Header
- mov [Word cs:Mus+(offset (SMus).HeaderLoc)+2],cs
- ; mov [Word cs:Mus+(offset (SMus).AnalyzerLoc)],offset AnalyzerHeights
- ; mov [Word cs:Mus+(offset (SMus).AnalyzerLoc)+2],cs
- mov [Word cs:Mus+(offset (SMus).PatternLoc)],offset PatternLoc
- mov [Word cs:Mus+(offset (SMus).PatternLoc)+2],cs
- mov [Word cs:Mus+(offset (SMus).InsLoc)],offset InsLoc
- mov [Word cs:Mus+(offset (SMus).InsLoc)+2],cs
- mov [Word cs:Mus+(offset (SMus).ChannelLoc)],offset Channel1
- mov [Word cs:Mus+(offset (SMus).ChannelLoc)+2],cs
- mov [Word cs:Mus+(offset (SMus).mt_PeriodTable)],offset mt_PeriodTable
- mov [Word cs:Mus+(offset (SMus).mt_PeriodTable)+2],cs
- mov [Byte cs:MUSOK],1
- mov si,[cs:GUSIRQ]
- mov di,[cs:u_Base]
- clc
- ret
- endp MUS_Init
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_Close - Kill all allocated segs, etc.
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_Close near
- call MUS_StopMusic
- call u_Reset
- mov bx,[cs:GUSIRQ]
- mov di,[Word cs:IntStore]
- mov si,[Word cs:IntStore+2]
- call RestoreVect
- mov [Byte cs:MUSOK],0
- ret
- endp MUS_Close
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_SetVars - Sets various parameters for the card.
- ; AX - Sampling Rate (on SB, ignored here...)
- ; CL - Max Volume Setting
- ; CH - IRQ = 0 if default
- ; DX - GUS address
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_SetVars near
- mov [cs:MaxVolume],cl
- or ch,ch
- jz @@NoIRQChange
- mov [Byte cs:GUSIRQ],ch
- @@NoIRQChange: or dx,dx
- jz @@NoAddrChange
- mov [cs:u_Base],dx
- add dx,102h
- mov [cs:u_Voice],dx
- inc dx
- mov [cs:u_Command],dx
- inc dx
- mov [cs:u_DataLo],dx
- inc dx
- mov [cs:u_DataHi],dx
- mov dx,[cs:u_Base]
- add dx,6
- mov [cs:u_Status],dx
- add dx,2
- mov [cs:u_TimerControl],dx
- inc dx
- mov [cs:u_TimerData],dx
- @@NoAddrChange: ret
- endp MUS_SetVars
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_PlayMusic - Make proper calls and interrupt sets for module playing.
- ; In: cx:si - PM Structure
- ;▓────────────────────────────────────────────────────────────────────────────▓
-
- proc MUS_PlayMusic near
- push ds
- mov ds,cx
- mov ax,[si+(offset (PM).MusBuf)+2]
- mov [cs:MusBuf],ax
- mov ax,[si+PM.mt_speed]
- cmp ax,-1
- jz @@SkipSpeed
- mov [Word cs:mt_speed],ax
- @@SkipSpeed: mov ax,[si+PM.mt_counter]
- cmp ax,-1
- jz @@SkipCounter
- mov [Word cs:mt_counter],ax
- @@SkipCounter: mov ax,[si+PM.mt_SongPos]
- mov [word cs:mt_SongPos],ax
- mov ax,[si+PM.mt_PatternPos]
- mov [Word cs:mt_PatternPos],ax
- mov ax,cs
- mov es,ax
- mov di,offset PS16Header
- push ds si
- lds si,[si+PM.Header]
- mov cx,PS16Size
- rep movsb
- pop si ds
- mov di,offset PatternLoc
- push ds si
- lds si,[si+PM.PatternLoc]
- mov cx,64*2
- rep movsb
- pop si ds
- mov di,offset InsLoc
- push ds si
- lds si,[si+PM.InsLoc]
- mov cx,32*4
- rep movsb
- pop si ds
- mov [Byte cs:MStatus],0
- call MUS_SetVoice
- call u_Reset
- mov bx,6
- call u_TurnOnUserInt
- pop ds
- ret
- endp MUS_PlayMusic
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_StopMusic - Shuts down the interrupts for generating music.
- ;▓────────────────────────────────────────────────────────────────────────────▓
-
- proc MUS_StopMusic near
- mov [Byte cs:MStatus],1
- call u_TurnOffUserInt
- call u_Reset
- ret
- endp MUS_StopMusic
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_SpeakerOn - Turns output speaker on.
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_SpeakerOn near
- mov dx,[cs:u_Base]
- mov al,00000000b
- out dx,al
- ret
- endp MUS_SpeakerOn
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_SpeakerOff - Turns output speaker off.
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_SpeakerOff near
- mov dx,[cs:u_Base]
- mov al,00000010b
- out dx,al
- ret
- endp MUS_SpeakerOff
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_ReturnInfo - Returns the SMUS structure location in SI:DI.
- ; In:
- ; CX - 1 = Copy info to SI:DI.
- ; 0 = Just return pointer.
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_ReturnInfo near
- mov ax,[cs:NumPatterns]
- mov [cs:offset Mus+(offset (SMus).NumPatterns)],ax
- mov al,[cs:mt_speed]
- mov [cs:offset Mus+(offset (SMus).mt_speed)],al
- mov al,[cs:mt_counter]
- mov [cs:offset Mus+(offset (SMus).mt_counter)],al
- mov ax,[cs:mt_PatternPos]
- mov [cs:offset Mus+(offset (SMus).mt_PatternPos)],ax
- mov al,[cs:mt_SongPos]
- mov [cs:offset Mus+(offset (SMus).mt_SongPos)],al
- mov al,[cs:PlayStatus]
- mov [cs:offset Mus+(offset (SMus).PlayStatus)],al
- mov ax,[cs:EditSeg]
- mov [cs:offset Mus+(offset (SMus).EditSeg)],ax
- mov ax,[cs:EditPat]
- mov [cs:offset Mus+(offset (SMus).EditPat)],ax
- mov ax,[cs:EditOfs]
- mov [cs:offset Mus+(offset (SMus).EditOfs)],ax
- mov al,[cs:MaxVolume]
- mov [cs:offset Mus+(offset (SMus).MaxVolume)],al
- mov al,[cs:SongLen]
- mov [cs:offset Mus+(offset (SMus).songlen)],al
- or cx,cx
- jnz @@CopyIt
- mov si,cs
- mov di,offset Mus
- ret
- @@CopyIt: push ds es
- mov es,si
- mov ax,cs
- mov ds,ax
- mov si,offset Mus
- mov cx,size Mus
- rep movsb
- pop es ds
- ret
- endp MUS_ReturnInfo
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_SetInfo - Sets the SMUS structure location to whatever is in SI:DI.
- ; In:
- ; CX - 1 = Set Max Volume
- ; 2 = Set Pattern Info
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_SetInfo near
- push cx ds es
- mov ds,si
- mov si,di
- mov ax,cs
- mov es,ax
- mov di,offset Mus
- mov cx,size Mus
- rep movsb
- pop es ds
- pop cx
- cli
- mov ax,[cs:offset Mus+(offset (SMus).NumPatterns)]
- mov [cs:NumPatterns],ax
- test cx,2
- jz @@SkipSetPat
- mov al,[cs:offset Mus+(offset (SMus).mt_speed)]
- mov [cs:mt_speed],al
- mov al,[cs:offset Mus+(offset (SMus).mt_counter)]
- mov [cs:mt_counter],al
- mov ax,[cs:offset Mus+(offset (SMus).mt_PatternPos)]
- mov [cs:mt_PatternPos],ax
- mov [cs:EditOfs],ax
- mov al,[cs:offset Mus+(offset (SMus).mt_SongPos)]
- mov [cs:mt_SongPos],al
- mov [Byte PTr cs:EditPat],al
- mov al,[cs:offset Mus+(offset (SMus).PlayStatus)]
- mov [cs:PlayStatus],al
- @@SkipSetPat: mov al,[cs:offset Mus+(offset (SMus).MaxVolume)]
- mov [cs:MaxVolume],al
- mov al,[cs:offset Mus+(offset (SMus).songlen)]
- mov [cs:SongLen],al
- test cx,1
- jz @@Leave
- call MUS_SetMaxVolume
- @@Leave: sti
- ret
- endp MUS_SetInfo
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_RetVoice
- ; In: AX - Voice
- ; ES:DX - Buffer from DRAM
- ; CX - Length
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; Dump sample to DRAM
- ; ES:BX - Max 64k sample to dump to RAM.
- ; SI:DI - DRAM location to dump to.
- ; CX - Max bytes to dump.
- ; AH - Xor value.
- proc MUS_RetVoice near
- call u_ReadPos
- call u_Peek
- mov si,ax
- ret
- endp MUS_RetVoice
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_RetMusicStatus
- ; Out: SI - 1 Music Stopped
- ; DI - 1 Scope Triggered
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_RetMusicStatus near
- mov al,[cs:MStatus]
- xor ah,ah
- mov si,ax
- mov al,[cs:Trigger]
- xor ah,ah
- mov di,ax
- mov [Byte cs:Trigger],0
- ret
- endp MUS_RetMusicStatus
-
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_DumpSampleDRAM
- ; CX - Sample Size
- ; SI:DI - Place in DRAM
- ; AX - Handle
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_DumpSampleDRAM near
- mov bx,ax
- call LoadDumpSample
- ret
- endp MUS_DumpSampleDRAM
-
- ; CX - Sample Size
- ; SI:DI - Place in DRAM
- ; BX - Handle
- ; DX - Sample Seg to read
- LDSeg dw 0
- proc LoadDumpSample near
- push cx bx
- mov [cs:LDSeg],dx
- pop bx
- push ds
- mov ah,3Fh
- mov dx,0
- mov ds,[cs:LDSeg]
- int 21h
- pop ds
-
- pop cx
- mov es,[cs:LDSeg]
- mov bx,0
- mov ah,0
- call u_DumpSampleToDRAM
- ret
- endp LoadDumpSample
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_SetMaxVolume - Set the Master volumes for the channels to the max value.
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_SetMaxVolume near
- mov al,[Byte cs:MaxVolume]
- mov [cs:offset Channel1+(offset (MS).MasterVolume)],al
- mov [cs:offset Channel2+(offset (MS).MasterVolume)],al
- mov [cs:offset Channel3+(offset (MS).MasterVolume)],al
- mov [cs:offset Channel4+(offset (MS).MasterVolume)],al
- ret
- endp MUS_SetMaxVolume
-
- ;▓────────────────────────────────────────────────────────────────────────────▓
- ; MUS_SetVoice -
- ;▓────────────────────────────────────────────────────────────────────────────▓
- proc MUS_SetVoice near
- mov cx,16
- mov bx,offset Channel1
- @@Looper: mov ax,0
- mov [Word cs:bx+MS.start],ax
- mov ax,0f000h
- mov [Word cs:bx+(offset (MS).start)+2],ax
- add bx,size MS
- loop @@Looper
- ret
- endp MUS_SetVoice
-
- ; GUS card routines.
-
- MaxVoices = 31
-
- IntStore dd 0
-
- MIDIIRQ dw 0
- GUSIRQ dw 0
- DMAIn dw 0
- DMAOut dw 0
- u_Base dw 0
-
- proc UDelay
- push dx ax
- mov dx,300h
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- pop ax dx
- ret
- endp UDelay
-
- ; BX:CX Set to whatever.
- proc u_Peek
- pushf
- cli
- push dx
- mov dx,[cs:u_Command]
- mov al,43h
- out dx,al
- inc dx ; 104h
- mov ax,cx
- out dx,ax
- dec dx ; 103h
- mov al,44h
- out dx,al
- add dx,2
- mov al,bl
- out dx,al
- add dx,2
- in al,dx
- pop dx
- popf
- ret
- endp u_Peek
-
- ; BX:CX Set to whatever.
- ; AX Value to poke
- proc u_Poke
- pushf
- cli
- push dx ax
- mov dx,[cs:u_Command]
- mov al,43h
- out dx,al
- inc dx
- mov ax,cx
- out dx,ax
- dec dx
- mov al,44h
- out dx,al
- add dx,2
- mov al,bl
- out dx,al
- add dx,2
- pop ax
- out dx,al
- in al,dx
- pop dx
- popf
- ret
- endp u_Poke
-
-
- ; DX - u_Base.
- proc u_Probe
- pushf
- cli
- mov dx,[cs:u_Command]
- mov al,4Ch
- out dx,al
- add dx,2 ; 105h
- mov al,0
- out dx,al
- call UDelay
- call UDelay
- sub dx,2 ; 103h
- mov al,4Ch
- out dx,al
- add dx,2 ; 105h
- mov al,1
- out dx,al
- call UDelay
- call UDelay
- mov ax,0AAh
- mov bx,0
- mov cx,0
- call u_Poke
- mov ax,055h
- mov bx,1
- call u_Poke
- mov bx,0
- call u_Peek
- push ax
- mov ax,0
- call u_Poke
- sub dx,2 ; 103h
- mov al,4Ch
- out dx,al
- add dx,2 ; 105h
- mov al,0
- out dx,al
- pop ax
- popf
- cmp al,0AAh
- jnz @@Nope
- clc
- ret
- @@Nope: stc
- ret
- endp u_Probe
-
- GUSChangeIRQ db 0,0,1,3,0,2,0,4,0,0,0,5,6,0,0,7
- GUSChangeDMA db 1,0,2,0,3,4,5
- ;1 5
- proc u_SetInterface
- cmp [Word cs:GUSIRQ],0
- jz @@Exit
- cli
- mov bx,[cs:MIDIIRQ]
- mov cl,[cs:bx+GUSChangeIRQ]
- shl cl,3
- mov bx,[cs:GUSIRQ]
- or cl,[cs:bx+GUSChangeIRQ]
- cmp bx,[cs:MIDIIRQ]
- jnz @@JustStore
- or cl,40h
- @@JustStore:
- push cx
- mov bx,[cs:DMAOut]
- dec bx
- mov cl,[cs:bx+GUSChangeDMA]
- mov dx,cx
- shl dl,3
- mov bx,[cs:DMAIn]
- dec bx
- mov cl,[cs:bx+GUSChangeDMA]
- inc bx
- cmp bx,[cs:DMAOut]
- jnz @@Fix
- or cl,40h
- jmp @@JustStore2
- @@Fix: or cl,dl
- @@JustStore2:
- mov bl,cl
- pop cx
- mov dx,[cs:u_Base]
- mov al,8
- out dx,al
- add dx,0Bh
- mov al,bl
- or al,80h
- out dx,al
- mov dx,[cs:u_Base]
- mov al,48h
- out dx,al
- add dx,0Bh
- mov al,cl
- out dx,al
- mov dx,[cs:u_Base]
- mov al,8
- out dx,al
- add dx,0Bh
- mov al,bl
- out dx,al
- mov dx,[cs:u_Base]
- mov al,48h
- out dx,al
- add dx,0Bh
- mov al,cl
- out dx,al
- mov dx,[cs:u_Base]
- add dx,102h
- mov al,0
- out dx,al
- mov dx,[cs:u_Base]
- mov al,9
- out dx,al
- mov dx,[cs:u_Base]
- add dx,102h
- mov al,0
- out dx,al
- sti
- @@Exit: ret
- endp u_SetInterface
-
- proc u_Reset
- call u_SetInterface
- cli
- mov bx,[cs:u_Command]
- mov cx,[cs:u_DataHi]
- mov dx,bx
- mov al,4Ch
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
- call UDelay
- call UDelay
- mov dx,bx
- mov al,4Ch
- out dx,al
- mov dx,cx
- mov al,1
- out dx,al
- call UDelay
- call UDelay
-
- mov dx,[cs:u_Voice]
- add dx,100h
- mov al,3
- out dx,al
- call UDelay
- mov dx,[cs:u_Voice]
- add dx,100h
- mov al,0
- out dx,al
-
-
- mov dx,bx
- mov al,41h
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
- mov dx,bx
- mov al,45h
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
- mov dx,bx
- mov al,49h
- out dx,al
- mov dx,cx
- mov al,0
- out dx,al
-
- mov dx,bx
- mov al,0Eh
- out dx,al
- add dx,2
- mov al,MaxVoices
- or al,0C0h
- out dx,al
-
- mov dx,[cs:u_Status]
- in al,dx
- mov dx,bx
- mov al,41h
- out dx,al
- mov dx,cx
- in al,dx
- mov dx,bx
- mov al,49h
- out dx,al
- mov dx,cx
- in al,dx
- mov dx,bx
- mov al,8Fh
- out dx,al
- mov dx,cx
- in al,dx
-
- push bx cx
- mov cx,0
- @@VoiceClearLoop:
- mov dx,[cs:u_Voice]
- mov al,cl
- out dx,al
- inc dx
- mov al,9
- out dx,al
- inc dl
- mov ax,0
- out dx,ax
- dec dl
- mov al,0
- out dx,al
- add dx,2
- mov al,3 ; Turn voice off
- out dx,al
- sub dx,2
- mov al,0Dh
- out dx,al
- add dx,2
- mov al,3
- out dx,al
- sub dx,2
- inc cx
- cmp cx,32
- jnz @@VoiceClearLoop
- pop cx bx
-
- mov dx,bx
- mov al,41h
- out dx,al
- mov dx,cx
- in al,dx
- mov dx,bx
- mov al,49h
- out dx,al
- mov dx,cx
- in al,dx
- mov dx,bx
- mov al,8Fh
- out dx,al
- mov dx,cx
- in al,dx
-
- mov dx,bx
- mov al,4Ch
- out dx,al
- mov dx,cx
- mov al,7
- out dx,al
- sti
- ret
- endp u_Reset
-
- ; CX:AX - Number
- proc RShift
- mov bx,cx
- shr ax,7
- shr cx,7
- shl bx,9
- or ax,bx
- ret
- endp RShift
-
- ; AX - Voice
- ; Returns: DX:AX - Position
- proc u_ReadPos
- pushf
- cli
- mov dx,[cs:u_Voice]
- out dx,al
- inc dx ; 103h
- mov al,8ah
- out dx,al
- inc dx ; 104h
- in ax,dx ; TEMP0
- mov cx,ax
- dec dx ; 103h
- mov al,8bh
- out dx,al
- inc dx ; 104h
- in ax,dx ; TEMP1
- xor dx,dx
- mov bx,cx
- shl cx,7
- shl dx,7
- shr bx,9
- or dx,bx
- shr ax,9
- and ax,7Fh
- or cx,ax
- mov ax,cx
- popf
- ret
- endp u_ReadPos
-
- ; Dump sample to DRAM
- ; ES:BX - Max 64k sample to dump to RAM.
- ; SI:DI - DRAM location to dump to.
- ; CX - Max bytes to dump.
- ; AH - Xor value.
- proc u_DumpSampleToDRAM
- cli
- push cx
- mov dx,[cs:u_Command]
- mov al,44h ; Dump upper byte, only do it on carry from now
- out dx,al ; on.
- add dx,2
- push ax
- mov ax,si
- out dx,al
- pop ax
- sub dx,2
- @@MainLoop:
- mov al,43h
- out dx,al
- inc dx
- push ax
- mov ax,di
- out dx,ax
- pop ax
- dec dx
- @@DumpByte:
- add dx,4
- mov al,[es:bx]
- xor al,ah
- inc bx
- out dx,al
- sub dx,4
- add di,1
- jnc @@DoLoop
- inc si
- mov al,44h
- out dx,al
- add dx,2
- push ax
- mov ax,si
- out dx,al
- pop ax
- sub dx,2
- @@DoLoop:
- loop @@MainLoop
- pop cx
- sti
- ret
- endp u_DumpSampleToDRAM
-
- u_Voice dw 0
- u_Command dw 0
- u_DataLo dw 0
- u_DataHi dw 0
- u_Status dw 0
- u_TimerControl dw 0
- u_TimerData dw 0
- u_adlibcontrol db 0
- u_timermask db 0
- u_IRQs db 2,3,5,7,11,12,15
- u_IntStore dd 0,0,0,0,0,0,0
-
- proc u_SetPorts
- mov dx,[cs:u_Base]
- add dx,102h
- mov [cs:u_Voice],dx
- inc dx
- mov [cs:u_Command],dx
- inc dx
- mov [cs:u_DataLo],dx
- inc dx
- mov [cs:u_DataHi],dx
- mov dx,[cs:u_Base]
- add dx,6
- mov [cs:u_Status],dx
- add dx,2
- mov [cs:u_TimerControl],dx
- inc dx
- mov [cs:u_TimerData],dx
- ret
- endp u_SetPorts
-
- ; In:
- ; DX - Base (0 for detect)
- ; CX - MIDI IRQ
- ; AX - IRQ (0 for detect)
- ; Carry set - No GUS
- ; No carry - GUS at u_Base
- proc u_DetectGUS
- mov [cs:GUSIRQ],ax
- mov [cs:MIDIIRQ],cx
- mov [cs:DMAIn],si
- mov [cs:DMAOut],di
- mov [cs:u_Base],dx
- call u_SetPorts
- clc
- ret
- endp u_DetectGUS
-
- ; bx - Speed (0-255) (* 80 microseconds)
- proc u_TurnOnUserInt
- cli
- or [Byte cs:u_adlibcontrol],4
- or [Byte cs:u_timermask],1
- mov dx,[cs:u_Command]
- mov al,46h
- out dx,al
- add dx,2
- mov al,bl
- out dx,al
- sub dx,2
- mov al,45h
- out dx,al
- add dx,2
- mov al,[cs:u_adlibcontrol]
- out dx,al
- mov dx,[cs:u_TimerControl]
- mov al,4
- out dx,al
- inc dx
- mov al,[cs:u_timermask]
- out dx,al
- sti
- ret
- endp u_TurnOnUserInt
-
- proc u_TurnOffUserInt
- cli
- and [Byte cs:u_adlibcontrol],0FBh
- and [Byte cs:u_timermask],0FEh
- mov dx,[cs:u_Command]
- mov al,45h
- out dx,al
- add dx,2
- mov al,[cs:u_adlibcontrol]
- out dx,al
- call u_Reset
- sti
- ret
- endp u_TurnOffUserInt
-
- irqstatus db 0
-
- proc GUSInt
- pusha
- push ds es
- mov dx,[cs:u_Status]
- in al,dx
- mov [cs:irqstatus],al
- @@TopOfInt: test [Byte cs:irqstatus],4
- jz @@CheckNext
- mov dx,[cs:u_Command]
- mov al,45h
- out dx,al
- and [Byte cs:u_adlibcontrol],0FBh
- add dx,2
- mov al,[cs:u_adlibcontrol]
- out dx,al
- or [Byte cs:u_adlibcontrol],4
- mov al,[cs:u_adlibcontrol]
- out dx,al
- call sd_UpdateChannels
- cmp [Byte cs:MStatus],1
- jnz @@CheckNext
- call u_TurnOffUserInt
- call u_Reset
- @@CheckNext: mov dx,[cs:u_Command]
- mov al,8Fh
- out dx,al
- add dx,2
- in al,dx
- @@Finish:
- mov al,20h
- out 0A0h,al
- mov al,20h
- out 20h,al
- sti
-
- pop es ds
- popa
- iret
- endp GUSInt
-
-
- proc FindOpenChannel
- mov bx,0
- @@Looper: cmp [cs:bx+ChannelMap],0
- jz @@Open
- inc bx
- cmp bx,32
- jnz @@Looper
-
- ; If we made it this far, check the priorities to turn one off.
- mov dx,0
- mov cx,0FFh ; Max Priority
- mov bx,0
- @@PLooper: cmp [cs:bx+ChannelPriority],cl
- jl @@Change
- jmp @@IncIt
- @@Change: mov cl,[cs:bx+ChannelPriority]
- mov dx,bx
- @@IncIt: inc bx
- cmp bx,32
- jnz @@PLooper
- mov bx,ax
-
-
- @@Open: mov ax,bx
- ret
- endp FindOpenChannel
-
- ;┌──────────────────────────────────────────────────────────────────────────┐
- ;│││──────────────────────── Protracker Stuff ────────────────────────────│││
- ;└──────────────────────────────────────────────────────────────────────────┘
- ;┌─┐ Protracker specific
- ;└─┘ variables.
- mt_speed db 6
- mt_counter db 0
- mt_PatternPos dw 0
- mt_SongPos db 0
- mt_PattDelayTime2 db 0
- mt_PattDelayTime db 0
- mt_PBreakFlag db 0
- mt_PBreakPos db 0
- mt_PosJumpFlag db 0
- mt_LowMask db 0FFh
- Trigger db 0
-
- mt_VibratoTable: db 0, 24, 49, 74, 97,120,141,161
- db 180,197,212,224,235,244,250,253
- db 255,253,250,244,235,224,212,197
- db 180,161,141,120, 97, 74, 49, 24
-
- Channel1 MS <0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 , 0,0,0>
- Channel2 MS <0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, 1,0,0>
- Channel3 MS <0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, 2,0,0>
- Channel4 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 , 3,0,0>
- Channel5 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 , 4,0,0>
- Channel6 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, 5,0,0>
- Channel7 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, 6,0,0>
- Channel8 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 , 7,0,0>
- Channel9 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 , 8,0,0>
- Channel10 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, 9,0,0>
- Channel11 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,0,0>
- Channel12 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 ,11,0,0>
- Channel13 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 ,12,0,0>
- Channel14 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,13,0,0>
- Channel15 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,14,0,0>
- Channel16 MS <0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 ,15,0,0>
-
-
- PlayStatus db 1
- MStatus db 0
- EditPat dw 0
- EditSeg dw 0
- EditOfs dw 0
- ChangeIns db 0
- MaxVolume db 200
- EfxFlag db 0
-
- mt_VolTable dw 00E00h,0B000h,0B800h,0BC00h,0BE00h,0C000h,0C400h,0C800h,0CC00h
- dw 0D000h,0D200h,0D400h,0D600h,0D800h,0DA00h,0DC00h,0DE00h
- dw 0E000h,0E100h,0E200h,0E300h,0E400h,0E500h,0E600h,0E700h
- dw 0E800h,0E900h,0EA00h,0EB00h,0EC00h,0ED00h,0EE00h,0EF00h
- dw 0F080h,0F100h,0F180h,0F200h,0F280h,0F300h,0F380h,0F400h
- dw 0F480h,0F500h,0F580h,0F600h,0F680h,0F700h,0F780h,0F800h
- dw 0F880h,0F900h,0F980h,0FA00h,0FA80h,0FB00h,0FB80h,0FC00h
- dw 0FC80h,0FD00h,0FD80h,0FE00h,0FE80h,0FF00h,0FF80h,0FFF0h
-
- include "period.asm"
-
- macro SetVoice
- mov [Byte cs:Voice],cl
- mov dx,[cs:u_Voice]
- mov al,[cs:si+MS.sc_Voice]
- out dx,al
- endm SetVoice
-
- Voice db 0
-
- macro PlayVol
- local Done
- mov dx,[cs:u_Command]
- mov al,89h
- out dx,al
- inc dl
- in ax,dx
- cmp ax,[cs:si+MS.sc_Vol]
- jz Done
- mov ax,[cs:si+MS.sc_Vol]
- call slideramp
- Done:
- endm PlayVol
-
- macro PlayNote
- local Done
- mov dx,[cs:u_Command]
- mov al,81h
- out dx,al
- inc dl
- in ax,dx
- cmp ax,[cs:si+MS.sc_Note]
- jz Done
- dec dl
- mov al,1
- out dx,al
- inc dl
- mov ax,[cs:si+MS.sc_Note]
- out dx,ax
- Done:
- endm PlayNote
-
- proc DecompressPattern near
- push di
- mov ax,es
- mov ds,ax
- mov ax,[cs:MusBuf]
- mov es,ax
- mov di,0
- mov cx,3072/2
- mov ax,0
- rep stosw
- mov si,0
- mov di,0
- mov al,[si+2]
- mov [cs:NumLines],al
- add si,3
- mov cx,0
- @@ChannelLoop: push cx
- mov di,cx
- shl cx,1
- add di,cx ; * 3
- @@LineLoop: xor ah,ah
- lodsb
- cmp al,-1
- jz @@NextChannel
- push di
- mov bx,ax
- shl ax,5 ; * 32
- shl bx,4 ; * 16
- add di,ax
- add di,bx
- movsb
- movsw
- pop di
- jmp @@LineLoop
- @@NextChannel: pop cx
- inc cx
- cmp cx,16
- jnz @@ChannelLoop
- pop di
- ret
- endp DecompressPattern
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ NAME : sd_UpdateChannels │
- ;│ *** Original code: Amiga Protracker by Lars Hamre. │
- ;│ *** Converted by Joshua C. Jensen. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- proc DecProc near
- cmp [cs:si+MS.DecVolume],0
- ja @@AllRight
- mov [Byte cs:si+MS.DecVolume],1
- @@AllRight:
- dec [Byte cs:si+MS.DecVolume]
- ret
- endp DecProc
-
- proc sd_UpdateChannels near
- mov ax,cs
- mov ds,ax
- mov es,ax
-
- mt_ContinueUpdate:
- inc [Byte cs:mt_counter]
- mov al,[cs:mt_counter]
- cmp al,[cs:mt_speed]
- jb mt_NoNewNote
- mov [Byte cs:mt_counter],0
- cmp [Byte cs:mt_PattDelayTime2],0
- jz mt_GetNewNote
- call mt_NoNewAllChannels
- jmp mt_dskip
-
- mt_NoNewNote:
- call mt_NoNewAllChannels
- jmp mt_NoNewPosYet
-
- mt_NoNewAllChannels:
- mov cx,16
- mov si,offset Channel1
- mt_NoNewLoop:
- push cx si
- call DecProc
- SetVoice
- call mt_CheckEfx
- PlayNote
- PlayVol
- pop si
- add si,size MS
- pop cx
- loop mt_NoNewLoop
- ret
-
- mt_GetNewNote:
- xor ax,ax
- mov al,[cs:mt_SongPos]
- mov di,ax
- mov [Word cs:EditPat],ax
- mov al,[cs:di+Sequences]
- shl al,1
- mov di,offset PatternLoc
- add di,ax
- mov es,[cs:di]
- mov di,[cs:mt_PatternPos]
- call DecompressPattern
- mov [Word cs:EditSeg],es
- mov [Word cs:EditOfs],di
-
- mov cx,16
- mov si,offset Channel1
- mt_GetNewLoop:
- push cx si
- call DecProc
- SetVoice
- call mt_PlayVoice
- PlayNote
- PlayVol
- pop si
- add si,size MS
- pop cx
- loop mt_GetNewLoop
- jmp mt_dskip
-
- mt_PlayVoice:
- mov [Byte cs:EfxFlag],0
- mov [Byte cs:ChangeIns],0
- cmp [Byte cs:si],0
- jnz mt_plvskip
- cmp [Word cs:si+1],0
- jnz mt_plvskip
- call mt_PerNop
- mt_plvskip:
- mov al,[es:di]
- mov [cs:si+MS.note],al
- mov ax,[es:di+1]
- mov [Word cs:si+MS.cmd],ax
- add di,3
-
- mov al,[cs:si+MS.cmd]
- and al,0F0h
- shr al,4
- mov ah,[Byte cs:si+MS.note]
- and ah,11000000b
- shr ah,2
- or al,ah ; Is there an ins?
- jz mt_SetRegisters
- mov [Byte cs:ChangeIns],1
- mov [cs:si+MS.sc_Mode],0
- dec al
- mov bl,al
- mov [cs:si+MS.SampleNum],al
- mov bh,size PS16Sample
- mul bh
- mov dx,ax
-
- xor bh,bh
- shl bx,2
- add bx,offset InsLoc
- mov ax,[cs:bx]
- mov [Word cs:si+MS.start],ax
- mov ax,[cs:bx+2]
- mov [Word cs:si+(offset (MS).start)+2],ax
- mov bx,dx
- add bx,offset Samples
- mov cx,[cs:bx+PS16Sample.length]
- mov [Word cs:si+MS.length],cx
- mov [Word cs:si+(offset (MS).length)+2],0
- mov ax,[Word cs:bx+PS16Sample.volume]
- mov [Word cs:si+MS.finetune],ax
- mov al,ah
- call volequ
-
- mov cx,[cs:bx+PS16Sample.replen]; Get the Repeat length.
- cmp cx,2
- jbe mt_NoLoop
- or [Byte cs:si+MS.sc_Mode],00001000b
- mov cx,[cs:bx+PS16Sample.repeat]
- or cx,cx
- je mt_LoopNoFix
- dec cx
- mt_LoopNoFix:
- mov ax,[Word cs:si+MS.start]
- mov dx,[Word cs:si+(offset (MS).start)+2]
- add ax,cx
- adc dx,0
- mov [Word cs:si+MS.loopstart],ax
- mov [Word cs:si+(offset (MS).loopstart)+2],dx
- mov [Word cs:si+MS.wavestart],ax
- mov [Word cs:si+(offset (MS).wavestart)+2],dx
- mov cx,[Word cs:bx+PS16Sample.replen]
- ; dec cx
- add ax,cx
- adc dx,0
- mov [Word cs:si+MS.replen],ax
- mov [Word cs:si+(offset (MS).replen)+2],dx
- jmp mt_SetRegisters
- mt_NoLoop:
- mov ax,[Word cs:si+MS.start]
- mov dx,[Word cs:si+(offset (MS).start)+2]
- mov [Word cs:si+MS.loopstart],ax
- mov [Word cs:si+(offset (MS).loopstart)+2],dx
- mov [Word cs:si+MS.wavestart],ax
- mov [Word cs:si+(offset (MS).wavestart)+2],dx
- mov cx,[Word cs:bx+PS16Sample.length]
- dec cx
- add ax,cx
- adc dx,0
- mov [Word cs:si+MS.replen],ax
- mov [Word cs:si+(offset (MS).replen)+2],dx
- mt_SetRegisters:
- mov al,[cs:si+MS.note]
- and al,00111111b
- jnz mt_ThereIsANote
- jmp mt_CheckMoreEfx
- mt_ThereIsANote:
- mov ax,[Word cs:si+MS.cmd]
- xchg ah,al
- and ax,0FF0h
- cmp ax,0E50h
- jz mt_DoSetFineTune
- cmp ah,3 ; Is it a tone portamento?
- jz mt_ChkTonePorta
- cmp ah,5 ; Is it a tone and volume slide?
- jz mt_ChkTonePorta
- cmp ah,9 ; Is it a sample offset command?
- jnz mt_SetPeriod
- call mt_CheckMoreEfx
- jmp mt_SetPeriod
-
- mt_DoSetFineTune:
- call mt_SetFineTune
- jmp mt_SetPeriod
-
- mt_ChkTonePorta:
- call mt_SetTonePorta
- jmp mt_CheckMoreEfx
-
- mt_SetPeriod:
- mov [Byte cs:ChangeIns],1
- mov bl,[cs:si+MS.note]
- and bx,00111111b
- dec bx
- shl bx,1
- mov al,[cs:si+MS.finetune]
- mov cl,61*2
- mul cl
- add bx,ax
- mov ax,[Word cs:bx+mt_PeriodTable]
- mov [cs:si+MS.period],ax
-
- mov ax,[Word cs:si+MS.cmd]
- xchg ah,al
- and ax,0FF0h
- cmp ax,0ED0h
- jnz mt_NotANoteCut
- jmp mt_CheckMoreEfx
- mt_NotANoteCut:
- mov al,[cs:si+MS.wavecontrol] ; Get the wavecontrol.
- and al,00000100b ; Amiga: BTST #2,wavecontrol.
- jz mt_vibnoc ; If it is zero, then skip.
- mov [Byte cs:si+MS.vibratopos],0
- mt_vibnoc:
- mov al,[cs:si+MS.wavecontrol] ; Get it again.
- and al,01000000b ; Amiga: BTST #6,wavecontrol
- jz mt_trenoc ; If it is zero, then skip.
- mov [Byte cs:si+MS.tremolopos],0 ; Zero the Tremolo offset.
- mt_trenoc:
- cmp [Byte cs:ChangeIns],1
- jnz mt_SetGeneral
- mt_DoIns:
- ; high byte of sample start == F000H, turn off the voice
- cmp [Word cs:si+(offset (MS).start)+2],0f000h
- jz @@NoVoice
- push dx ax
- mov al,0
- call doramp
- mov dx,[cs:u_Command]
- mov al,0
- out dx,al
- mov al,3
- add dl,2
- out dx,al
- xor [cs:si+MS.sc_Voice],16
- mov dx,[cs:u_Voice]
- mov al,[cs:si+MS.sc_Voice]
- out dx,al
- pop ax dx
-
- ; Send sample begin
- @@DoBegin:
- mov dx,[cs:u_Command]
- mov al,0ah
- out dx,al
- inc dx ; 104h
- mov ax,[Word cs:si+MS.start]
- mov cx,[Word cs:si+(offset (MS).start)+2]
- call RShift
- out dx,ax
- dec dx ; 103h
- mov al,0bh
- out dx,al
- inc dx ; 104h
- mov ax,[Word cs:si+MS.start]
- shl ax,9
- out dx,ax
-
- mov dx,[cs:u_Command]
- mov al,2
- out dx,al
- inc dx ; 104h
- mov ax,[Word cs:si+MS.loopstart]
- mov cx,[Word cs:si+(offset (MS).loopstart)+2]
- call RShift
- out dx,ax
- dec dx ; 103h
- mov al,3
- out dx,al
- inc dx ; 104h
- mov ax,[Word cs:si+MS.loopstart]
- shl ax,9
- out dx,ax
-
- mov dx,[cs:u_Command]
- mov al,4
- out dx,al
- inc dx ; 104h
- mov ax,[Word cs:si+MS.replen]
- mov cx,[Word cs:si+(offset (MS).replen)+2]
- call RShift
- out dx,ax
- dec dx ; 103h
- mov al,5
- out dx,al
- inc dx ; 104h
- mov ax,[Word cs:si+MS.replen]
- shl ax,9
- out dx,ax
- dec dx ; 103h
- mov al,0
- out dx,al
- add dx,2
- mov al,[Byte cs:si+MS.sc_Mode]
- out dx,al
- mt_SetGeneral:
- call mt_PerNop
- mov dx,[cs:u_Command]
- mov al,0ch
- out dx,al
- add dx,2
- mov al,[cs:si+MS.sc_PanPosition]
- out dx,al
- sub dx,2
- jmp @@Bottom
-
- ; Shuts off the voice
- @@NoVoice:
- mov al,0
- call doramp
- mov al,0
- out dx,al
- add dl,2
- mov al,3
- out dx,al
- @@Bottom:
- @@Done:
- mov ax,[cs:si+MS.period]
- ; call SpectrumAnalyzer
- ; ST n_trigger(A6)
- mov [Byte cs:Trigger],1
- cmp [Byte cs:EfxFlag],1
- jz @@Skip
- call mt_CheckMoreEfx
- @@Skip: ret
- endp sd_UpdateChannels
-
- proc mt_dskip near
- mov [Word cs:EditSeg],es
- mov ax,[Word cs:mt_PatternPos]
- mov [Word cs:EditOfs],ax
- add [Word cs:mt_PatternPos],48
- mov al,[cs:mt_PattDelayTime]
- or al,al
- jz mt_dskc
- mov [cs:mt_PattDelayTime2],al
- mov [Byte cs:mt_PattDelayTime],0
- mt_dskc:
- cmp [Byte cs:mt_PattDelayTime2],0
- jz mt_dska
- dec [Byte cs:mt_PattDelayTime2]
- jz mt_dska
- sub [Word cs:mt_PatternPos],48
- mt_dska:
- cmp [Byte cs:mt_PBreakFlag],0
- jz mt_nnpysk
- mov [Byte cs:mt_PBreakFlag],0
- xor ax,ax
- mov al,[cs:mt_PBreakPos]
- mov [cs:mt_PBreakPos],ah
- mov bx,48
- mul bx
- mov [cs:mt_PatternPos],ax
- mt_nnpysk:
- cmp [Word cs:mt_PatternPos],1024*3
- jb mt_NoNewPosYet
-
- mt_NextPosition:
- xor ax,ax
- mov al,[cs:mt_PBreakPos]
- mov bx,48
- mul bx
- mov [cs:mt_PatternPos],ax
- mov [Byte cs:mt_PBreakPos],0
- mov [Byte cs:mt_PosJumpFlag],0
- inc [Byte cs:mt_SongPos]
- and [Byte cs:mt_SongPos],7Fh
- mov al,[cs:mt_SongPos]
- cmp al,[cs:SongLen]
- jnz mt_NoNewPosYet
- mov [Byte cs:mt_SongPos],0
- cmp [Byte cs:PlayStatus],1
- jnz @@Quit
- mov [Byte cs:mt_SongPos],0
- ret
- ;---------------------------------------------------
- @@Quit: mov [Byte cs:MStatus],1
- mov [Byte cs:mt_SongPos],0
- ret
-
- mt_NoNewPosYet:
- cmp [Byte cs:mt_PosJumpFlag],0
- jnz mt_NextPosition
- ret
- endp mt_dskip
-
- proc mt_CheckEfx near
- mov ax,[Word cs:si+MS.cmd]
- xchg al,ah
- and ax,0FFFh
- jz mt_Return
- mov bl,[cs:si+MS.cmd]
- and bl,0Fh
- cmp bl,0
- jz mt_Arpeggio
- cmp bl,1
- jz mt_PortaUp
- cmp bl,2
- jz mt_PortaDown
- cmp bl,3
- jz mt_TonePortamento
- cmp bl,4
- jz mt_Vibrato
- cmp bl,5
- jz mt_TonePlusVolSlide
- cmp bl,6
- jz mt_VibratoPlusVolSlide
- cmp bl,0Eh
- jz mt_E_Commands
- SetBack:call mt_PerNop
- cmp bl,7
- jz mt_Tremolo
- cmp bl,0Ah
- jz mt_VolumeSlide
- mt_Return:
- ret
- endp mt_CheckEfx
-
- ; Effect 0 -- Arpeggio
- proc mt_Arpeggio near
- xor ax,ax
- mov al,[cs:mt_counter]
- mov bl,3
- div bl
- xchg al,ah
- cmp al,1
- jz mt_Arpeggio1
- cmp al,2
- jz mt_Arpeggio2
- mt_Arpeggio0:
- mov cx,[cs:si+MS.period]
- jmp ArpeggioSet
-
- mt_Arpeggio1:
- xor ax,ax
- mov al,[Byte cs:si+MS.cmdlo]
- shr al,4
- jmp ArpeggioFind
-
- mt_Arpeggio2:
- xor ax,ax
- mov al,[cs:si+MS.cmdlo]
- and al,15
- ArpeggioFind:
- shl ax,1
- mov bx,ax
- mov al,[cs:si+MS.finetune]
- mov cl,61*2
- mul cl
- mov dx,[cs:si+MS.period]
- push di
- mov di,offset mt_PeriodTable
- add di,ax
- mov cx,60
- mt_arploop:
- mov ax,[cs:bx+di]
- cmp dx,[cs:di]
- jnb mt_arpafterloop
- add di,2
- loop mt_arploop
- pop di
- ret
- mt_arpafterloop:
- pop di
- mov cx,ax
-
- ArpeggioSet:
- call mt_PerNop2
- ret
- endp mt_Arpeggio
-
- ; Effect 1 -- Portamento Up
- proc mt_PortaUp near
- xor ax,ax
- mov al,[cs:si+MS.cmdlo]
- and al,[cs:mt_LowMask]
- mov [Byte cs:mt_LowMask],0FFh
- sub [cs:si+MS.period],ax
- mov cx,[cs:si+MS.period]
- and cx,0FFFh
- cmp cx,71h
- jnb mt_PortaUSkip
- and [cs:si+MS.period],0F000h
- or [cs:si+MS.period],71h
- mt_PortaUSkip:
- mov cx,[cs:si+MS.period]
- and cx,0FFFh
- call mt_PerNop
- ret
- endp mt_PortaUp
-
-
- ; Effect 2 -- Portamento Down
- proc mt_PortaDown near
- xor ax,ax
- mov al,[cs:si+MS.cmdlo]
- and al,[cs:mt_LowMask]
- mov [Byte cs:mt_LowMask],0FFh
- add [cs:si+MS.period],ax
- mov cx,[cs:si+MS.period]
- and cx,0FFFh
- cmp cx,358h
- jb mt_PortaDSkip
- and [cs:si+MS.period],0F000h
- or [cs:si+MS.period],856
- mt_PortaDSkip:
- mov cx,[cs:si+MS.period]
- and cx,0FFFh
- call mt_PerNop
- ret
- endp mt_PortaDown
-
- proc mt_SetTonePorta near
- push di
- mov di,offset mt_PeriodTable
- mov bl,[cs:si+MS.note]
- and bx,00111111b
- dec bx
- shl bx,1
- mov dx,[Word cs:bx+di]
- xor ax,ax
- mov al,[cs:si+MS.finetune]
- mov cl,61*2
- mul cl
- add di,ax
- mov bx,0
- mt_StpLoop:
- cmp dx,[cs:bx+di]
- jnb mt_StpFound
- add bx,2
- cmp bx,61*2
- jb mt_StpLoop
- mov bx,59*2
- mt_StpFound:
- mov dl,[cs:si+MS.finetune]
- and dl,8
- jz mt_StpGoss
- or bx,bx
- jz mt_StpGoss
- sub bx,2
- mt_StpGoss:
- mov dx,[cs:bx+di]
- pop di
- mov [cs:si+MS.wantedperiod],dx
- mov ax,[cs:si+MS.period]
- mov [Byte cs:si+MS.toneportdirec],0
- cmp dx,ax
- jz mt_ClearTonePorta
- jnb mt_Return
- mov [Byte cs:si+MS.toneportdirec],1
- ret
-
- mt_ClearTonePorta:
- mov [Word cs:si+MS.wantedperiod],0
- ret
- endp mt_SetTonePorta
-
-
- ; Effect 3 -- Tone Portamento
- proc mt_TonePortamento near
- mov al,[cs:si+MS.cmdlo]
- or al,al
- jz mt_TonePortNoChange
- mov [cs:si+MS.toneportspeed],al
- mov [Byte cs:si+MS.cmdlo],0
- mt_TonePortNoChange:
- cmp [Word cs:si+MS.wantedperiod],0
- jz mt_Return
- xor ax,ax
- mov al,[cs:si+MS.toneportspeed]
- cmp [Byte cs:si+MS.toneportdirec],0
- jnz mt_TonePortaUp
- mt_TonePortaDown:
- add [cs:si+MS.period],ax
- mov ax,[cs:si+MS.wantedperiod]
- cmp ax,[cs:si+MS.period]
- jg mt_TonePortaSetPer
- mov [cs:si+MS.period],ax
- mov [Word cs:si+MS.wantedperiod],0
- jmp mt_TonePortaSetPer
-
- mt_TonePortaUp:
- sub [cs:si+MS.period],ax
- mov ax,[cs:si+MS.wantedperiod]
- cmp ax,[cs:si+MS.period]
- jl mt_TonePortaSetPer
- mov [cs:si+MS.period],ax
- mov [Word cs:si+MS.wantedperiod],0
-
- mt_TonePortaSetPer:
- mov cx,[cs:si+MS.period]
- mov al,[cs:si+MS.glissfunk]
- and al,0Fh
- jz mt_GlissSkip
- mov al,[cs:si+MS.finetune]
- mov bl,61*2
- mul bl
- push di
- mov di,offset mt_PeriodTable
- add di,ax
- mov bx,0
- mt_GlissLoop:
- cmp cx,[cs:bx+di]
- jnb mt_GlissFound
- add bx,2
- cmp bx,61*2
- jb mt_GlissLoop
- mov bx,59*2
- mt_GlissFound:
- mov cx,[cs:bx+di]
- pop di
- mt_GlissSkip:
- call mt_PerNop2
- ret
- endp mt_TonePortamento
-
-
- ; Effect 4 -- Vibrato
- proc mt_Vibrato near
- mov al,[cs:si+MS.cmdlo]
- or al,al
- jz mt_Vibrato2
- mov cl,[cs:si+MS.vibratocmd]
- and al,0fh
- jz mt_vibskip
- and cl,0F0h
- or cl,al
- mt_vibskip:
- mov al,[cs:si+MS.cmdlo]
- and al,0F0h
- jz mt_vibskip2
- and cl,0Fh
- or cl,al
- mt_vibskip2:
- mov [cs:si+MS.vibratocmd],cl
- mt_Vibrato2:
- mov al,[cs:si+MS.vibratopos]
- mov bx,offset mt_VibratoTable
- shr ax,2
- and ax,001Fh
- xor cx,cx
- mov cl,[cs:si+MS.wavecontrol]
- and cl,03h
- jz mt_vib_sine
- shl al,3
- cmp cl,1
- jz mt_vib_rampdown
- mov cl,255
- jmp mt_vib_set
- mt_vib_rampdown:
- cmp [Byte cs:si+MS.vibratopos],0
- jnl mt_vib_rampdown2
- mov cl,255
- sub cl,al
- jmp mt_vib_set
- mt_vib_rampdown2:
- mov cl,al
- jmp mt_vib_set
- mt_vib_sine:
- add bl,al
- mov cl,[cs:bx]
- mt_vib_set:
- mov al,[cs:si+MS.vibratocmd]
- and al,15
- mul cl
- shr ax,7
- mov cx,ax
- mov ax,[cs:si+MS.period]
- cmp [Byte cs:si+MS.vibratopos],0
- jl mt_VibratoNeg ; BMI
- add ax,cx
- jmp mt_Vibrato3
- mt_VibratoNeg:
- sub ax,cx
- mt_Vibrato3:
- mov cx,ax
- call mt_PerNop2
- mov al,[cs:si+MS.vibratocmd]
- shr ax,2
- and ax,3Ch
- add [cs:si+MS.vibratopos],al
- ret
- endp mt_Vibrato
-
-
- ; Effect 5 -- Tone and Volume Slide
- proc mt_TonePlusVolSlide near
- call mt_TonePortNoChange
- jmp mt_VolumeSlide
- endp mt_TonePlusVolSlide
-
- ; Effect 6 -- Vibrato and Volume Slide
- proc mt_VibratoPlusVolSlide near
- call mt_Vibrato2
- jmp mt_VolumeSlide
- endp mt_VibratoPlusVolSlide
-
-
- ; Effect 7 -- Tremolo
- proc mt_Tremolo near
- mov al,[Byte cs:si+MS.cmdlo]
- or al,al
- jz mt_Tremolo2
- mov cl,[cs:si+MS.tremolocmd]
- and al,0Fh
- jz mt_treskip
- and cl,0F0h
- or cl,al
- mt_treskip:
- mov al,[Byte cs:si+MS.cmdlo]
- and al,0F0h
- jz mt_treskip2
- and cl,0Fh
- or cl,al
- mt_treskip2:
- mov [cs:si+MS.tremolocmd],cl
- mt_Tremolo2:
- mov al,[cs:si+MS.tremolopos]
- shr al,2
- and ax,001Fh
- xor cx,cx
- mov cl,[cs:si+MS.wavecontrol]
- shr cl,4
- and cl,03h
- jz mt_tre_sine
- shl al,3
- cmp cl,1
- jz mt_tre_rampdown
- mov cl,255
- jmp mt_tre_set
- mt_tre_rampdown:
- cmp [Byte cs:si+MS.vibratopos],0
- jnb mt_tre_rampdown2
- mov cl,255
- sub cl,al
- jmp mt_tre_set
- mt_tre_rampdown2:
- mov cl,al
- jmp mt_tre_set
- mt_tre_sine:
- xor bx,bx
- mov bl,al
- mov cl,[cs:bx+offset mt_VibratoTable]
- mt_tre_set:
- mov al,[cs:si+MS.tremolocmd]
- and al,0Fh
- mul cl
- mov cx,ax
- shr cx,6
- mov al,[cs:si+MS.volume]
- cmp [Byte cs:si+MS.tremolopos],0
- jb mt_TremoloNeg ; BMI jns
- add al,cl
- jmp mt_Tremolo3
- mt_TremoloNeg:
- sub al,cl
- mt_Tremolo3:
- jnb mt_TremoloSkip
- xor ax,ax
- mt_TremoloSkip:
- cmp al,40h
- jb mt_TremoloOK ; BLS
- mov al,40h
- mt_TremoloOK:
- call volequ
- mov al,[cs:si+MS.tremolocmd]
- shr al,2
- and al,3Ch
- add [cs:si+MS.tremolopos],al
- ret
- endp mt_Tremolo
-
- ; Effect 9 -- Sample Offset
- proc mt_SampleOffset near
- mov al,[Byte cs:si+MS.cmdlo]
- or al,al
- jz mt_sononew
- mov [cs:si+MS.sampleoffset],al
- mt_sononew:
- mov al,[cs:si+MS.sampleoffset] ; Variance in Protracker code.
- shl ax,8
- ; cmp ax,[cs:si+MS.reallength]
- ; jge mt_sofskip
- mov cx,ax
- or cx,cx
- jnz mt_dontset
- dec cx
- mt_dontset:
- mov ax,[Word cs:si+MS.start]
- mov dx,[Word cs:si+(offset (MS).start)+2]
- add ax,cx
- adc dx,0
- mov [Word cs:si+MS.start],ax
- mov [Word cs:si+(offset (MS).start)+2],dx
- ret
- mt_sofskip:
- ret
- endp mt_SampleOffset
-
-
- ; Effect A -- Volume Slide
- proc mt_VolumeSlide near
- mov al,[cs:si+MS.cmdlo]
- shr al,4
- or al,al
- jz mt_VolSlideDown
- mt_VolSlideUp:
- add [Byte cs:si+MS.volume],al
- cmp [Byte cs:si+MS.volume],40h
- jb mt_vsuskip
- mov [Byte cs:si+MS.volume],40h
- mt_vsuskip:
- mov al,[Byte cs:si+MS.volume]
- call volequ
- ret
-
- mt_VolSlideDown:
- mov al,[cs:si+MS.cmdlo]
- and al,0Fh
- mt_VolSlideDown2:
- sub [Byte cs:si+MS.volume],al
- jnb mt_vsdskip
- mov [Byte cs:si+MS.volume],0
- mt_vsdskip:
- mov al,[Byte cs:si+MS.volume]
- call volequ
- ret
- endp mt_VolumeSlide
-
-
- ; Effect B -- Position Jump
- proc mt_PositionJump near
- mov al,[Byte cs:si+MS.cmdlo] ; Get where to jump
- dec al ; Update the
- mov [cs:mt_SongPos],al ; information.
- mt_pj2: mov [Byte cs:mt_PBreakPos],0
- mov [Byte cs:mt_PosJumpFlag],1
- ret
- endp mt_PositionJump
-
- ; Effect C -- Volume Change
- proc mt_VolumeChange near
- mov al,[Byte cs:si+MS.cmdlo] ; Get value for volume
- cmp al,40h ; Is it greater than 40h?
- jb mt_VolumeOK ; Nope
- mov al,40h
- mt_VolumeOK:
- mov [cs:si+MS.volume],al ; Get it again
- call volequ
- ret
- endp mt_VolumeChange
-
- ; Effect D -- Pattern Break
- proc mt_PatternBreak near
- mov al,[Byte cs:si+MS.cmdlo] ; Break to where?
- mov cl,al
- shr al,4
- mov bl,10
- mul bl
- and cl,0Fh
- add al,cl
- cmp al,63
- jg mt_pj2
- mov [cs:mt_PBreakPos],al
- mov [Byte cs:mt_PosJumpFlag],1
- ret
- endp mt_PatternBreak
-
-
- ; Effect F -- Set Speed
- ; Doesn't handle Protracker extended speeds.
- proc mt_SetSpeed near
- mov al,[Byte cs:si+MS.cmdlo] ; Get value for speed
- or al,al
- jz mt_SpeedLeave
- cmp al,32
- jnb mt_SpeedExt
- mt_SpeedSet:
- mov [Byte cs:mt_counter],0
- mov [Byte cs:mt_speed],al
- mt_SpeedLeave:
- ret
- mt_SpeedExt:
- ret
- endp mt_SetSpeed
-
-
- proc mt_CheckMoreEfx near
- mov bl,[cs:si+MS.cmd]
- and bl,0Fh
- cmp bl,09h
- jz mt_SampleOffset
- cmp bl,0Bh
- jz mt_PositionJump
- cmp bl,0Dh
- jz mt_PatternBreak
- cmp bl,0Eh
- jz mt_E_Commands
- cmp bl,0Fh
- jz mt_SetSpeed
- cmp bl,0Ch
- jz mt_VolumeChange
- jmp mt_PerNop
- endp mt_CheckMoreEfx
-
- proc mt_E_Commands near
- mov bl,[Byte cs:si+MS.cmdlo]
- and bl,0F0h
- shr bl,4
- cmp bl,0
- jz mt_FilterOnOff
- cmp bl,1
- jz mt_FinePortaUp
- cmp bl,2
- jz mt_FinePortaDown
- cmp bl,3
- jz mt_SetGlissControl
- cmp bl,4
- jz mt_SetVibratoControl
- cmp bl,5
- jz mt_SetFineTune
- cmp bl,6
- jz mt_JumpLoop
- cmp bl,7
- jz mt_SetTremoloControl
- cmp bl,0Eh
- jz mt_PatternDelay
- cmp bl,9
- jz mt_RetrigNote
- cmp bl,0Ah
- jz mt_VolumeFineUp
- cmp bl,0Bh
- jz mt_VolumeFineDown
- cmp bl,0Ch
- jz mt_NoteCut
- cmp bl,0Dh
- jz mt_NoteDelay
- ret
- endp mt_E_Commands
-
- ;──────────────────────────────────────────────────────────────────────────
- ; Effect E
- ;──────────────────────────────────────────────────────────────────────────
- ; Effect 0 -- FilterOnOff
- proc mt_FilterOnOff near
- mov al,[Byte cs:si+MS.cmdlo]
- and al,1
- sal al,1
- ; Amiga
- ; Stuff
- ret
- endp mt_FilterOnOff
-
- ; Effect 1 -- Fine Porta Up
- proc mt_FinePortaUp near
- cmp [Byte cs:mt_counter],0
- jnz mt_Return
- mov [Byte cs:mt_LowMask],0Fh
- jmp mt_PortaUp
- endp mt_FinePortaUp
-
- ; Effect 2 -- Fine Porta Down
- proc mt_FinePortaDown near
- cmp [Byte cs:mt_counter],0
- jnz mt_Return
- mov [Byte cs:mt_LowMask],0Fh
- jmp mt_PortaDown
- endp mt_FinePortaDown
-
- ; Effect 3 -- Set Gliss Control
- proc mt_SetGlissControl near
- mov al,[Byte cs:si+MS.cmdlo]
- and al,0Fh
- and [Byte cs:si+MS.glissfunk],0F0h
- or [cs:si+MS.glissfunk],al
- ret
- endp mt_SetGlissControl
-
- ; Effect 4 -- Set Vibrato Control
- proc mt_SetVibratoControl near
- mov al,[cs:si+MS.cmdlo]
- and al,0Fh
- and [Byte cs:si+MS.wavecontrol],0F0h
- or [cs:si+MS.wavecontrol],al
- ret
- endp mt_SetVibratoControl
-
- ; Effect 5 -- Set Fine Tune
- proc mt_SetFineTune near
- mov al,[cs:si+MS.cmdlo]
- and al,0Fh
- mov [cs:si+MS.finetune],al
- ret
- endp mt_SetFineTune
-
- ; Effect 6 -- Jump Loop
- proc mt_JumpLoop near
- cmp [Byte cs:mt_counter],0
- jnz mt_Return
- mov al,[cs:si+MS.cmdlo]
- and al,0Fh
- jz mt_SetLoop
- cmp [Byte cs:si+MS.loopcount],0
- jz mt_jumpcnt
- dec [Byte cs:si+MS.loopcount]
- jz mt_Return
- mt_jmploop:
- mov al,[cs:si+MS.pattpos]
- mov [cs:mt_PBreakPos],al
- mov [Byte cs:mt_PBreakFlag],1
- ret
-
- mt_jumpcnt:
- mov [cs:si+MS.loopcount],al
- jmp mt_jmploop
-
- mt_SetLoop:
- ; xor dx,dx
- mov ax,[cs:mt_PatternPos]
- mov bx,48
- ; call DivIt
- div bl
- and ax,63
- mov [cs:si+MS.pattpos],al
- ret
- endp mt_JumpLoop
-
- ; Effect 7 -- Set Tremolo Control
- proc mt_SetTremoloControl near
- mov al,[Byte cs:si+MS.cmdlo]
- and al,0Fh
- shl al,4
- and [Byte cs:si+MS.wavecontrol],0Fh
- or [cs:si+MS.wavecontrol],al
- ret
- endp mt_SetTremoloControl
-
- ; Effect 9 -- Retrig Note
- proc mt_RetrigNote near
- mov bl,[Byte cs:si+MS.cmdlo]
- and bl,0Fh
- jz mt_rtnend
- xor ax,ax
- mov al,[cs:mt_counter]
- or al,al
- jnz mt_rtnskp
- mov al,[cs:si+MS.note]
- or al,al
- jnz mt_rtnend
- ; mov [Byte cs:mt_counter],0
- xor ax,ax
- mov al,[cs:mt_counter]
- mt_rtnskp:
- div bl
- xchg ah,al
- or al,al
- jnz mt_rtnend
- mt_DoRetrig:
- mov [Byte cs:EfxFlag],1
- call mt_DoIns
- mov [Byte cs:EfxFlag],0
- mt_rtnend:
- ret
- endp mt_RetrigNote
-
- ; Effect A -- Volume Fine Up
- proc mt_VolumeFineUp near
- cmp [Byte cs:mt_counter],0
- jnz mt_Return
- mov al,[cs:si+MS.cmdlo]
- and al,0Fh
- jmp mt_VolSlideUp
- endp mt_VolumeFineUp
-
- ; Effect B -- Volume Fine Down
- proc mt_VolumeFineDown near
- cmp [Byte cs:mt_counter],0
- jnz mt_Return
- mov al,[cs:si+MS.cmdlo]
- and al,0Fh
- jmp mt_VolSlideDown2
- endp mt_VolumeFineDown
-
- ; Effect C -- Note Cut
- proc mt_NoteCut near
- mov al,[Byte cs:si+MS.cmdlo]
- and al,0Fh
- cmp al,[cs:mt_counter]
- jnz mt_Return
- mov [Byte cs:si+MS.volume],0
- mov al,[Byte cs:si+MS.volume]
- call volequ
- ret
- endp mt_NoteCut
-
- ; Effect D -- Note Delay
- proc mt_NoteDelay near
- mov al,[Byte cs:si+MS.cmdlo]
- and al,0Fh
- cmp al,[cs:mt_counter]
- jnz mt_Return
- mov al,[cs:si]
- and al,00111111b
- jz mt_Return
- jmp mt_DoRetrig
- endp mt_NoteDelay
-
- ; Effect E -- Pattern Delay
- proc mt_PatternDelay near
- cmp [Byte cs:mt_counter],0
- jnz mt_Return
- mov al,[Byte cs:si+MS.cmdlo]
- and al,0Fh
- cmp [Byte cs:mt_PattDelayTime2],0
- jnz mt_Return
- inc al
- mov [cs:mt_PattDelayTime],al
- ret
- endp mt_PatternDelay
-
- proc doramp near
- push bx si
- mov ah,0
- cmp [Byte cs:si+MS.MasterVolume],0
- jz @@ZeroVol
- mul [Byte cs:si+MS.MasterVolume]
- inc ah
- @@ZeroVol:
- mov bl,ah
- xor bh,bh
- shl bx,1
- mov ax,[cs:bx+mt_VolTable]
- jmp slideramp2
- slideramp:
- push bx si
- slideramp2:
- mov si,ax
- mov dx,[cs:u_Command]
- mov al,0Dh
- out dx,al
- add dl,2
- mov al,3
- out dx,al
- sub dl,2
- mov al,89h
- out dx,al
- inc dx
- in ax,dx
- push si
- push ax
- shr ax,8
- shr si,8
- cmp ax,si
- jz @@Done2
- jb @@OK
- xchg si,ax
- @@OK:
- push ax
- mov dx,[cs:u_Command]
- mov al,7
- out dx,al
- add dx,2
- pop ax
- out dx,al
- mov dx,[cs:u_Command]
- mov al,8
- out dx,al
- add dx,2
- mov ax,si
- out dx,al
- mov dx,[cs:u_Command]
- mov al,6
- out dx,al
- add dx,2
- mov al,00111111b
- out dx,al
- mov bl,00000000b
- pop ax
- pop si
- cmp ax,si
- jb @@OK2
- or bl,01000000b
- @@OK2:
- mov dx,[cs:u_Command]
- mov al,0Dh
- out dx,al
- add dx,2
- mov al,bl
- out dx,al
- jmp @@Done
-
- @@Done2:
- pop ax ax
- @@Done:
- pop si bx
- ret
- endp doramp
-
- proc volequ near
- push bx si
- mov [cs:si+MS.DecVolume],al
- mov ah,0
- cmp [Byte cs:si+MS.MasterVolume],0
- jz @@ZeroVol
- mul [Byte cs:si+MS.MasterVolume]
- inc ah
- @@ZeroVol:
- mov bl,ah
- xor bh,bh
- shl bx,1
- mov ax,[cs:bx+mt_VolTable]
- @@Skip: mov [cs:si+MS.sc_Vol],ax
- pop si bx
- ret
- endp volequ
-
- proc DivIt near
- or bx,bx
- stc
- jz Div1
- mov cx,ax
- mov ax,dx
- xor dx,dx
- div bx
- xchg cx,ax
- div bx
- xchg dx,cx
- clc
- Div1: ret
- endp DivIt
-
- proc mt_PerNop near
- mov cx,[cs:si+MS.period] ; get period Value
- proc mt_PerNop2 near
- mov ax,cx
- and ax,0FFFh
- or ax,ax
- jz @@OutIt
- push dx bx ax
- mov bx,19
- mov dx,36h
- mov ax,9E9Ah
- call DivIt
- pop bx
- call DivIt
- pop bx dx
- @@OutIt: mov [cs:si+MS.sc_Note],ax
- ret
- endp mt_PerNop2
- endp mt_PerNop
-
- SizeSoundSeg = $-StartSoundSeg
-
- ends GUSSound
-
-